package com.deyuanyun.pic.settings.support.shiro;

import com.deyuanyun.pic.common.spring.SpringAppliction;
import com.deyuanyun.pic.common.util.ajax.AjaxSupport;
import com.deyuanyun.pic.common.util.web.RequestResponseContext;
import com.deyuanyun.pic.settings.domain.prvlg.CustomUser;
import com.deyuanyun.pic.settings.service.prvlg.UserService;
import com.deyuanyun.pic.settings.support.cache.SessionCacheSupport;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.filter.authc.UserFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 *  重写shiro记住我部分代码，重写的目的主要是为了解决现有系统中:<br>
 *  1、调用{@link SessionCacheSupport#getSessionVO()}报空指针<br>
 *  2、踢不出去人的bug<br>
 *  <b>未来重构这部分代码的时候这个酌情考虑是否需要</b>
 *  @author axiao(xj08.dream@gmail.com)
 *  @date 2017-01-13
 *  @version 1.0
 *  Histroy: [修改人][时间][描述]
 */
public class CustomUserFilter extends UserFilter {

    private static final Logger log  = LoggerFactory.getLogger(CustomUserFilter.class);


    /**
     * 允许访问的时候进入
     * @param request
     * @param response
     * @param mappedValue
     * @return
     */
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {

        if (isLoginRequest(request, response)) {
            return true;
        } else {
            Subject subject = getSubject(request, response);
            // If principal is not null, then the user is known and should be allowed access.
            String userName = (String) subject.getPrincipal();
            if(com.deyuanyun.pic.common.util.StringUtils.isNotEmpty(userName)) {
                Object o = subject.getSession().getAttribute(SessionCacheSupport.USERLOGINID);
                if( o == null){//判断是否已经放入Session，如果未放入才放入，要不然记住密码的登录的时候，永远会放入最新的sessionid。
                    subject.getSession().setAttribute(SessionCacheSupport.USERLOGINID + "__", userName);
                    subject.getSession().setAttribute(SessionCacheSupport.USERLOGINID, userName);
                    UserService userService = SpringAppliction.getBean(UserService.class);
                    List<CustomUser> userList = userService.getUser(userName);
                    com.deyuanyun.pic.settings.support.SecurityUtils.setUser(userList.get(0));   
                }
                return true;
            }
            return false;
        }
    }

    /**
     * 因为项目中的request、response是绑定到线程中的，所以必须要这样写，要不然用到的地方取不到值要报错，这代码加的。。。
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
        /* 让shiro来往RequestResponseContext中保存request，response到当前线程中，
         shiro在spring mvc之前所以，spring mvc不再需要往RequestResponseContext中保存request，response到当前线程*/
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        RequestResponseContext.setRequest(httpServletRequest);
        RequestResponseContext.setResponse(httpServletResponse);
        return super.preHandle(request, response);
    }
}
